<?php
// +----------------------------------------------------------------------
// | 后台用户管理
// +----------------------------------------------------------------------
namespace app\common\model;
use think\Model;
use think\Validate;


class Goods extends Model
{
	use \base\model\ModelTrait;
	
	// ----------------
	// ---模型事件---
	//----------------
	protected static function init()
	{
    	//插入前验证
    	self::event('before_insert', function ($param) {
	    	$validate = new Validate;
			$validate->rule([
				'cate_id|系统分类'=>'require|integer',
				'shop_id'=>'require|integer',
				'shop_cate_id|店铺分类'=>'require|integer',
				'freight_id|运费模板'=>'require|integer',
				'img|商品主图'=>'require|url',
				'banners|商品轮播图'=>'require',
		    	'name|商品名称' => 'require',
		      	'price|商品价格' => 'require|float|min:0',
		      	'sale_price|商品销售价格' => 'require|float|min:0',
		    	'stock|库存' => 'require|float',
		    	'postage' => 'float|min:0',
		    	'warn_stock' => 'float|min:0',
		    	'status' => 'integer|in:-1,0,1,2',
		    	'is_customized' => 'require|integer|in:0,1'
			]);
	        if(!$validate->check($param)){
	        	throw new \think\Exception($validate->getError());
	        }
	      	$param['sort_no'] =  model('Goods')->max('id') + 1;
        });
    }
	
	//自动完成
	protected $insert = ['goods_no'];
	protected function setGoodsNoAttr() {
		$code = rand(10000000, 999999999);
        if( self::where('goods_no',$code)->find() )  return $this->setGoodsNoAttr();
        return $code;
    }
	
	//评论，一对多关联
	public function replyList(){
        return $this->hasMany('goods_reply','goods_id','id');
    }
	
	//店铺，一对一关联
	public function shopInfo(){
        return $this->hasOne('shop','id','shop_id')->bind([
        	'shop_name'=>'name',
        	'shop_logo'=>'img',
        ]);
    }
	
	//店铺商品状态，一对多关联 
	public function goodsStatus(){
        return $this->hasMany('goods_status','goods_id');
    }
	
	//商品规格，一对多关联
	public function goodsSpecs(){
        return $this->hasMany('goods_specs','goods_id');
    }
    
    //套餐内商品列表，一对多关联 
	public function goodsMeal(){
        return $this->hasMany('GoodsMeal','pid','id');
    }
	
	//获取器-是否限时抢购
	public function getIsBenefitAttr($value,$data){
		if($value == 1 && $data['benefit_end_at'] && $data['benefit_end_at'] > date("Y-m-d H:i:s")){
			return 1;
		}else{
			return 0;
		}
    }
	
	//获取器-月份时间
	public function getMonthAttr($value,$data){
    	return date_format(date_create($data['add_time']),'m月d日');
    }
	
	//获取器-销售价格
	public function getSalePriceAttr($value,$data){
		if($data['is_benefit'] == 1 || $data['is_integral_gift'] == 1){
			return $value;
		}else{
			$discounts = (float)( $data['discounts'] ?: 10 );
			return round( (float)($value ?: 0) * ( $discounts / 10 ) , 2);
		}
    }
	
	//设置器-商品详情-html编码
	public function setRemarkAttr($value){
		return htmlspecialchars($value);
    }
	
	//获取器-商品详情-html编码
	public function getRemarkAttr($value){
		return htmlspecialchars_decode($value);
    }
	
    // ----------------
	// ---获取模型-包含店铺，等级优惠等信息处理---
	//----------------
	protected  $get_model_shop_id = 0;
	protected  $get_model_user_id = 0;
    //设置店铺
    public function setShop($id=0){ $this->get_model_shop_id = $id; return $this; }
    //设置用户id
    public function setUser($id=0){ $this->get_model_user_id = $id; return $this; }
    //获取模型
	public  function getModel($specs_id=0)
	{
		//基础参数
		$shopId =  $this->get_model_shop_id ?: request()->shopId ?: 0;
		$uid = $this->get_model_user_id ?: request()->userInfo['id'] ?: 0;
		$userLevel = model('user_vip')->where('uid',$uid)->value('level') ?: 0;
		
		//模型
    	$model = self::alias('a');
		$model = $model->leftJoin("GoodsStatus b",'b.goods_id = a.id and b.shop_id = '.$shopId);
		$model = $model->leftJoin("GoodsSpecs c","c.goods_id = a.id and ".(
			$specs_id === '*' ? '1=1' :
			($specs_id ? "c.id=$specs_id" : "c.is_default=1")
		));
		$model = $model->leftJoin("GoodsSpecsStock k",'k.specs_id = c.id and k.shop_id = '.$shopId);
		$model = $model->leftJoin("GoodsSpecsProfit d",'d.specs_id = c.id and d.level='.$userLevel);
		$model = $model->leftJoin("GoodsCate e",'e.id = a.cate_id');
		$model = $model->leftJoin("GoodsCateLevel f",'e.id = f.cate_id and f.level='.$userLevel);
		$model = $model->leftJoin("UserLevel g",'g.level='.$userLevel);
		$model = $model->leftJoin("Shop s",'s.id = a.shop_id');
		$model = $model->leftJoin(
			"(
				select uid,goods_id,count(*) as num from xw_user_stars 
				where type='collect' 
				group by uid,goods_id
			) n",
			"n.goods_id=a.id and n.uid=$uid"
		);
		//字段取值
    	$model = $model->field('
    		a.id,
    		a.sales,
    		a.id as goods_id,
    		a.goods_no,
    		a.name as goods_name,
    		a.img as goods_img,
    		a.banners as goods_banners,
    		a.type as goods_type,
    		a.is_integral_gift,
    		a.info as goods_info,
    		a.give_type,
    		a.remark as goods_remark,
    		a.cate_id,
    		a.shop_id,
    		if( a.is_benefit = 1 and  a.benefit_start_at < now() and a.benefit_end_at > now(),
    			1, 0 
    		) as is_benefit,
    		a.benefit_start_at,
    		a.benefit_end_at,
    		a.effective_time,
    		a.freight_id,
    		s.name as shop_name,
    		if(ifnull(f.discounts,-1) !=-1,
				if(f.discounts<=0,10,f.discounts),
				if(g.discounts<=0,10,g.discounts)
			)  as parent_discounts,
    		if(	ifnull(d.discounts,-1) !=-1 , 
    			if(d.discounts<=0 ,10,d.discounts),
				if(ifnull(f.discounts,-1) !=-1,
					if(f.discounts<=0,10,f.discounts),
					if(g.discounts<=0,10,g.discounts)
				) 
			) as discounts,
			ifnull(
    			if( a.is_benefit = 1 and  a.benefit_start_at < now() and a.benefit_end_at > now(), 
	    			(k.benefit_stock - k.benefit_frozen_stock),
	    			(k.stock - k.frozen_stock)
	    		)
    		,0) as stock,
    		ifnull(c.name,"") specs_name,
    		ifnull(c.id,"") specs_id,
    		ifnull(c.price,0) price,
    		ifnull(c.cost_price,0) cost_price,
    		ifnull(
    			if( a.is_benefit = 1 and  a.benefit_start_at < now() and a.benefit_end_at > now(), 
	    			c.benefit_sale_price,
	    			c.sale_price
	    		)
    		,0) as sale_old_price,
    		ifnull(
    			if( a.is_benefit = 1 and  a.benefit_start_at < now() and a.benefit_end_at > now(), 
	    			c.benefit_sale_price,
	    			c.sale_price
	    		)
    		,0) as sale_price,
    		ifnull(c.use_price,0) use_price,
    		ifnull(c.use_integral,0) use_integral,
    		if(n.num > 0,1,0)  as is_stars,
    		is_gm_upgrade,
    		is_low_level_gm,
    		upgrade_level
    	');
    	$model = $model->field("$userLevel as user_level");
    	//只获取正常状态的商品
    	$model = $model->where('a.status',1);
		$model = $model->where('a.is_del',0);
		$model = $model->where('a.is_apply',1);
		//只获取总店和可售卖的当前用户对应分店的商品
		$model = $model->where(function ($query) use($shopId) {
			$query->where('a.shop_id',$shopId);
			$query->whereOr(function ($query) use($shopId) {
				$query->where('a.shop_id', 0);
				$query->where(function ($query) use($shopId) {
					$query->where('a.is_top', 1);
					$query->whereOr('ifnull(b.is_del,1) != 1');
				});
				//只获取已上架的商品和强制上架的商品
				$query->where(function ($query) use($shopId) {
					$query->where('b.status',1);
					$query->whereOr('a.is_top',1);
				});
				//只获取可售卖的商品
				$query->where(function ($query) use($shopId) {
					$query->whereNull('a.sale_shop_id');
					$query->whereOr('a.sale_shop_id','');
					$query->whereOr('a.sale_shop_id',0);
					$query->whereOr([['','exp',\Db::raw("find_in_set($shopId,a.sale_shop_id)")]]);
				});
			});
		});
		//判断当前分类状态是否正常
		$model = $model->where(function ($query){
			$query->where('e.is_del', 0);
		    $query->where('e.is_show',1);
		});
		//判断当前店铺状态是否正常
		$model = $model->where(function ($query){
			$query->where('s.is_del', 0);
		    $query->where('s.is_enable',1);
		});
		//判断当前商品是否开启购买升级
		$model = $model->where(function ($query) use($userLevel) {
			$query->where('a.is_gm_upgrade',0);
		    $query->whereor(function($query) use($userLevel) {
		    	$query->where('a.is_gm_upgrade',1);
		    	$query->where('a.is_low_level_gm',1);
		    	$query->where('a.upgrade_level','>',$userLevel);
		    });
		});
		//分页排序
		$model = $model->page(input('pageIndex') ?: 1,input('pageSize') ?: 20);
		$model = $model->order('a.is_top,a.sales desc,a.sort_no asc');
		
    	//返回模型
		return $model;
    }
	
	/**
     * 获取商品列表 - 自动变化库存-价格等信息（秒杀）
     * @return type
     */
	public function getList($cateid='',$name='')
    {
    	$model = self::getModel();
      	//$model = $model->where('type','<>',1);
		$model = $model->where('a.is_integral_gift',0);
		$cateid && $model = $model->where('a.cate_id',$cateid);
		$name && $model = $model->where('a.name','like',"%".$name."%");
		return $model->select();
    }

	/**
     * 获取商品详情 - 自动变化库存-价格等信息（秒杀）
     * @return type
     */
	public function details($goods_id,$specs_id=0)
    {
    	$shopId = $shopId ?: request()->shopId ?: 0;
    	$goods = self::getModel($specs_id)->get($goods_id);
    	if($goods && $specs_id===0){
    		//商品规格-------
    		$goods['specs_list'] = $specsLlist = self::getGoodsSpecs($goods,$shopId);
    		//统计
			$goods['specs_num'] = count($specsLlist);
			$goods['count_stock'] = array_sum( array_column($specsLlist,'stock') );
			//商品评论------
			$goods['reply_list'] =  $goods->replyList()->where('is_del',0)->page(1,5)->select();
    	}
    	if($goods){
    		//商品详情格式转换
			$goods['goods_remark'] = htmlspecialchars_decode( $goods['goods_remark'] );
			//包含项目 - 套餐类
			$goods['proj_list'] 	=  $goods->goodsMeal()->with(['goods','specs'])->select();
			$goods['total_num'] = $goods->goodsMeal()->sum('num');
    	}
		//返回
		return $goods;
    }
	
	/**
    * 获取商品规格
    * @param type $uid
    * @return type
    */
	public function getGoodsSpecs($goods,$shopId)
    {
    	//商品规格-------
		$discounts = $goods['parent_discounts'] <= 0 ? 10 : $goods['parent_discounts'];
		$is_benefit = $goods['is_benefit'];  $img = $goods['goods_img'];
		return $goods->goodsSpecs()->alias('a')
			->leftJoin("GoodsSpecsProfit d",'d.specs_id = a.id and d.level='.$goods['user_level'])
			->leftJoin("GoodsSpecsStock k",'k.specs_id = a.id and k.shop_id = '.$shopId)
			//->where('a.status',1)
			->where('a.is_del',0)
			->field("
    			a.id, a.goods_id, a.name, a.price, a.cost_price,
    			'$img' as img,
    			
    			if( $is_benefit = 1, a.benefit_sale_price, a.sale_price ) as sale_old_price,
    			
    			if( $is_benefit = 1, a.benefit_sale_price, 
    				round( 
    					a.sale_price * ( if( ifnull(d.discounts,-1) !=-1, (d.discounts/10) , $discounts / 10) )
    				,2)
    			)  as sale_price,
    			
    			if( ifnull(d.discounts,-1) !=-1, d.discounts,  $discounts )  as discounts,
    			
    			a.use_price,
    			a.use_integral,
    			a.give_integral,
    			ifnull(
	    			if( $is_benefit = 1, 
		    			(k.benefit_stock - k.benefit_frozen_stock),
		    			(k.stock - k.frozen_stock)
		    		)
	    		,0) as stock
    		")
			->select()->toArray();
    }
	
	
	
	/**
    * 获取最近购买列表
    * @param type $uid
    * @return type
    */
	public function latelyBuy($uid)
    {
    	$model = self::getModel();
    	$model = $model->join('order_goods h','h.goods_id = a.id');
		$model = $model->leftJoin('(select goods_id,count(id) as buy_count from xw_order_goods  group by goods_id) j','j.goods_id = a.id');
    	$model = $model->leftJoin('order k','k.id = h.order_id');
    	$model = $model->group('h.goods_id');
    	$model = $model->where('k.uid',$uid);
    	$model = $model->field('j.buy_count');
    	$model = $model->field('h.add_time as buy_time');
		$model = $model->order('h.add_time', 'desc');
		return $model ->all();
    }
	
	/**
    * 获取商品评论
    * @param type $id
    * @return type
    */
	public function getGoodsReplyList($goods_id,$pageIndex=1,$pageSize=20)
    {
		return model('goods_reply')->getGoodsList($goods_id,$pageIndex,$pageSize);
    }
	
	
	/**
     * 添加或更新商品
     * @return type
     */
	public function addAndUpdate($data){
		//判断是否存在商品规格
		if( !$data['specs'] || !$specs = json_decode($data['specs'],true) ){
			$this -> errorInfo = "规格参数错误！";
			return false;
		}
		
		//判断库存
		if( $data['stock'] != array_sum(array_column($specs, 'stock')) ){
			$this -> errorInfo = "商品总库存不等于规格库存之和！";
			return false;
		}
		
		//验证默认值
		$is_default_num = 0;
		foreach ($specs as $key => $value) {
			if($value['is_default'] == 1){
				$data['price'] = (float)$value['price'];
				$data['sale_price'] =  (float)$value['sale_price'];
				$is_default_num ++;
			}
		}
		if( $is_default_num!=1 ){
			$this -> errorInfo = "规格必须存在一个默认值，且不能多个！";
			return false;
		}
		
		\Db::startTrans();
		try {
			$goodsSpecs  = model('GoodsSpecs');
			if(!$res = self::allowField(true)->isUpdate($data['id'] ? true :false )->save($data)){
				$this -> errorInfo = "异常错误！";
				return false;
   			}
			if( !$goodsSpecs->addOrUpdateSpecs($data['shop_id'],$this->id,$specs) ){
				\Db::rollback();
				$this -> errorInfo = $goodsSpecs->errorInfo;
				return false;
			}
		    // 提交事务
		    \Db::commit();
			return $this->id;
		} catch (\Exception $e) {
		    // 回滚事务
		    \Db::rollback();
			$this -> errorInfo = "异常错误！";
			return false;
		}
    }
	
	/**
    * 上架
    * @param type $id
    * @return type
    */
	public function grounding($id)
    {
    	$model = self::get($id);
		if( $model->status == 0){
			$this -> errorInfo = '商品未审核，不能上架';
            return false;
		}
		if( $model->status == -1){
			$this -> errorInfo = '商品审核未通过，不能上架';
            return false;
		}
		if( $model->status == 1){
            return true;
		}else{
			$model->status =  '1';
			return $model->save();
		}
    }
	
	/**
    * 下架
    * @param type $id
    * @return type
    */
	public function undercarriage($id)
    {
    	$model = self::get($id);
		if( $model->status != 1 ){
          	$this -> errorInfo = '商品并未上架';
            return false;
		}else{
			$model->status =  '2';
			return $model->save();
		}
    }
	
	/**
    * 审核
    * @param type $id
    * @return type
    */
	public function approval($id,$status,$status_desc='')
    {
    	if(!trim($id) || !trim($status) || ($status != 1 && $status != -1)){
			$this -> errorInfo = '参数不对！';
            return false;
		}
		if($status==-1 && !trim($status_desc)){
			$this -> errorInfo = '失败原因必填！';
            return false;
		}
    	$model = self::get($id);
		if( $model->status != 0 ){
          	$this -> errorInfo = '商品已审核！';
            return false;
		}else{
			$model->status = $status;
			$model->status_desc = $status_desc;
			return $model->save();
		}
    }
	
	
}
